package com.itaming.lycheeframework.security.config;

import com.itaming.lycheeframework.security.authentication.AuthContextProvider;
import com.itaming.lycheeframework.security.authentication.TokenInterceptor;
import com.itaming.lycheeframework.security.properties.LycheeSecurityProperties;
import com.itaming.lycheeframework.security.token.TokenService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.lang.NonNull;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.Collections;
import java.util.Set;

/**
 * Security模块WebMvc配置类
 *
 * @author A.Ming
 */
@RequiredArgsConstructor
public class SecurityWebMvcConfiguration implements WebMvcConfigurer {

    /**
     * Security配置参数
     */
    private final LycheeSecurityProperties securityProperties;

    /**
     * Token服务
     */
    private final TokenService tokenService;

    /**
     * 认证上下文提供者
     */
    private final ObjectProvider<AuthContextProvider<?, ?>> authContextProvider;

    /**
     * 添加拦截器
     *
     * @param registry
     */
    @Override
    public void addInterceptors(@NonNull InterceptorRegistry registry) {
        if (securityProperties.getAuth().isEnabled()) {
            // 添加认证拦截器
            registry.addInterceptor(new TokenInterceptor(tokenService, authContextProvider.getIfAvailable(EmptyAuthContextProvider::new)))
                .addPathPatterns("/**")
                .excludePathPatterns(securityProperties.getAuth().getExcludePath());
        }
    }

    /**
     * 空认证上下文提供者
     */
    private static class EmptyAuthContextProvider implements AuthContextProvider<Object, Object> {

        @Override
        public Object getUser(Object userId) {
            return null;
        }

        @Override
        public Set<String> getPermissions(Object userId) {
            return Collections.emptySet();
        }

        @Override
        public Set<String> getRoles(Object userId) {
            return Collections.emptySet();
        }

        @Override
        public boolean isAdmin(Object user, Set<String> roles) {
            return false;
        }

        @Override
        public boolean isSuperAdmin(Object user, Set<String> roles) {
            return false;
        }

    }

}
